package image_utils

import (
	"encoding/base64"
	"github.com/corona10/goimagehash"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"os"
)

type ImgSimilarHash struct {
	AvgHash  *goimagehash.ImageHash
	DiffHash *goimagehash.ImageHash
	PerHash  *goimagehash.ImageHash
}

func CalImgSimilarHash(img image.Image) (*ImgSimilarHash, error) {
	var err error
	bpHash := &ImgSimilarHash{}
	bpHash.AvgHash, err = goimagehash.AverageHash(img)
	if err != nil {
		return nil, err
	}
	bpHash.DiffHash, err = goimagehash.DifferenceHash(img)
	if err != nil {
		return nil, err
	}
	bpHash.PerHash, err = goimagehash.PerceptionHash(img)
	if err != nil {
		return nil, err
	}
	return bpHash, nil
}

func LoadImageFromPath(filePath string) (image.Image, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	img, _, err := image.Decode(file)
	if err != nil {
		return nil, err
	}

	return img, nil
}

func HashIsSimilar(source, target *ImgSimilarHash, similarPer float64) (bool, error) {
	avg, err := CalHanDisToSimilar(source.AvgHash, target.AvgHash)
	if err != nil {
		return false, err
	}
	per, err := CalHanDisToSimilar(source.PerHash, target.PerHash)
	if err != nil {
		return false, err
	}
	diff, err := CalHanDisToSimilar(source.DiffHash, target.DiffHash)
	if err != nil {
		return false, err
	}
	d := (per + diff + avg) / 3
	return d >= similarPer, nil
}

func CalHanDisToSimilar(hash1, hash2 *goimagehash.ImageHash) (float64, error) {
	distance, err := hash1.Distance(hash2)
	if err != nil {
		return 0, err
	}
	ssim := 1.0 - float64(distance)/64.0 // Assuming a 64-bit hash

	return ssim, nil
}

// ImageToBase64 获取本地图片字节流
func ImageToBase64(imagePath string) (string, error) {
	// 读取图片文件
	imageFile, err := os.ReadFile(imagePath)
	if err != nil {
		return "", err
	}
	// 将图片内容转换为Base64编码
	base64Encoded := base64.StdEncoding.EncodeToString(imageFile)
	return base64Encoded, nil
}

func isJPEG(data []byte) bool {
	return len(data) >= 2 && data[0] == 0xFF && data[1] == 0xD8 // JPEG标志位
}

func isPNG(data []byte) bool {
	return len(data) >= 8 && data[1] == 'P' && data[2] == 'N' && data[3] == 'G' && data[4] == '\r' && data[5] == '\n' && data[6] == 0x1A && data[7] == '\n' // PNG标志位
}

func SaveBase64Image(imageBase64 string) (string, error) {
	//log.Info("imageData", log.Content{"data": imageBase64})
	imageData, err := base64.StdEncoding.DecodeString(imageBase64)
	if err != nil {
		return "", err
	}
	isPng := false
	if isPNG(imageData) {
		isPng = true
	}
	filename := "eq/1.jpg"
	if isPng {
		filename = "eq/1.png"
	}
	if err = os.WriteFile(filename, imageData, 0666); err != nil {
		return "", err
	}
	return filename, nil
}
